#!/bin/bash
# openqrm-client	openQRM init script for the managed resources
#
# chkconfig: 2345 98 19
# description: openQRM is the next generation Linux Data Center management

# support for LSB init scripts
### BEGIN INIT INFO
# Provides: openqrm-client
# Required-Start: $all
# Required-Stop: $all
# Default-Start:  2 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: openQRM init script for the managed resources
# Description: openQRM init script for the managed resources
### END INIT INFO

#
# openQRM Enterprise developed by openQRM Enterprise GmbH.
#
# All source code and content (c) Copyright 2014, openQRM Enterprise GmbH unless specifically noted otherwise.
#
# This source code is released under the GNU General Public License version 2, unless otherwise agreed with openQRM Enterprise GmbH.
# The latest version of this license can be found here: src/doc/LICENSE.txt
#
# By using this software, you acknowledge having read this license and agree to be bound thereby.
#
#           http://openqrm-enterprise.com
#
# Copyright 2014, openQRM Enterprise GmbH <info@openqrm-enterprise.com>
#

export LANG=C
PATH=/usr/bin:/sbin:/bin:/usr/sbin
export PATH
LOCKFILE=/var/lock/subsys/openqrm
mkdir -p $(dirname $LOCKFILE)

export `eval cat /proc/cmdline`	2>/dev/null
. /var/openqrm/openqrm-resource.conf
# make sure to have a valid backup of the parameters, at least including the openQRM server ip
if [ ! -f /var/openqrm/openqrm-resource.conf.last ]; then
	/bin/cp -f /var/openqrm/openqrm-resource.conf /var/openqrm/openqrm-resource.conf.last
fi
if [ "$resource_mac" == "" ]; then
	/bin/cp -f /var/openqrm/openqrm-resource.conf.last /var/openqrm/openqrm-resource.conf
	. /var/openqrm/openqrm-resource.conf
fi
export OPENQRM_SERVER_BASE_DIR=$resource_basedir
export OPENQRM_SOURCE_DIR=$resource_basedir/openqrm
. $resource_basedir/openqrm/include/openqrm-functions
. $resource_basedir/openqrm/include/openqrm-package-functions


# define max-start-retries
MAX_START_RETRY=120

# define wget to use with https
if [ "$openqrm_web_protocol" == "https" ]; then
	WGET="wget -q --no-check-certificate"
else
	WGET="wget -q"
fi

# gets/starts/stops enabled boot-services for the resources
function openqrm_boot_service() {
	local BOOT_SERVICE=$1
	local BOOT_SERVICE_CMD=$2
	local CURRENT=`pwd`

	# get + install the package during start
	if [ "$BOOT_SERVICE_CMD" == "start" ]; then
		echo "Getting boot-service package $BOOT_SERVICE"
		mkdir -p  $resource_basedir/openqrm/plugins/$BOOT_SERVICE
		cd $resource_basedir/openqrm/plugins/$BOOT_SERVICE
		if ! $WGET $openqrm_web_protocol://$resource_openqrmserver/openqrm/boot-service/boot-service-$BOOT_SERVICE.tgz; then
			echo "ERROR: Could not get boot-service package for boot-service $BOOT_SERVICE !"
			return 1
		fi
		tar -xzf boot-service-$BOOT_SERVICE.tgz
		rm -f boot-service-$BOOT_SERVICE.tgz
		# get optional custom appliance config
		if [ "$appliance_name" != "" ]; then
			if [ ! -d $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/ ]; then
				mkdir -p $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/
			fi
			if $WGET -O $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/openqrm-plugin-$BOOT_SERVICE.conf.$appliance_name.conf $openqrm_web_protocol://$resource_openqrmserver/openqrm/boot-service/plugins/$BOOT_SERVICE/openqrm-plugin-$BOOT_SERVICE.$appliance_name.conf; then
				echo "- applying custom $BOOT_SERVICE boot-service configuration for appliance $appliance_name"
				/bin/cp -f $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/openqrm-plugin-$BOOT_SERVICE.conf $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/openqrm-plugin-$BOOT_SERVICE.conf.default
				/bin/cp -f $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/openqrm-plugin-$BOOT_SERVICE.conf.$appliance_name.conf $resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/openqrm-plugin-$BOOT_SERVICE.conf
			fi
		fi
	fi
	# run the boot-service cmd
	BOOT_SERVICE_INIT="$resource_basedir/openqrm/plugins/$BOOT_SERVICE/etc/init.d/$BOOT_SERVICE"
	if [ -x $BOOT_SERVICE_INIT ]; then
		echo "Running $BOOT_SERVICE_CMD on boot-service $BOOT_SERVICE"
		$BOOT_SERVICE_INIT $BOOT_SERVICE_CMD
	fi
	cd $CURRENT
}





function openqrm_client_start() {
	echo "Starting openQRM-client"
	openqrm_client_stop 1>/dev/null 2>&1
	START_RETRY=0
	LOOP_CONNECT=0
	MAX_CONNECT=10
	# checks
	umount /initrd/lib/modules 1>/dev/null 2>&1
	umount /initrd/boot 1>/dev/null 2>&1
	umount /initrd/ 1>/dev/null 2>&1
	grep -q "/initrd" /proc/mounts && umount /initrd
	chmod 666 /dev/null
	if [ ! -e /dev/tty ]; then
		cd /dev
		mknod tty c 5 0
		cd
	fi

	# network up ?
	echo "NOTICE: Checking connection to openQRM server at $resource_openqrmserver"
	while ! $WGET -q -t 1 -T 4 -O /dev/null "$openqrm_web_protocol://$resource_openqrmserver/openqrm/action/resource-monitor.php"; do
		echo -n "."
		sleep 2
		LOOP_CONNECT=$(( LOOP_CONNECT + 1 ))
		if [ "$LOOP_CONNECT" == "$MAX_CONNECT" ]; then
			echo "WARNING: Could not connect to openQRM server at $resource_openqrmserver! Trying to continue ..."
			break
		fi
	done
	# check if we have resource_mac, if not try to find the right interface integrated in openQRM
	if ifconfig -a | grep ^eth | grep -i $resource_mac &>/dev/null; then
		# if not in the initrd try to refresh the resource parameters
		if [ ! -f /etc/initrd-devices.conf ]; then
			if ! $WGET -q -t 1 -T 4 -O /var/openqrm/openqrm-resource.conf "$openqrm_web_protocol://$resource_openqrmserver/openqrm/action/resource-monitor.php?resource_command=get_parameter&resource_mac=$resource_mac"; then
				# restore
				/bin/cp -f /var/openqrm/openqrm-resource.conf.last /var/openqrm/openqrm-resource.conf
				echo "NOTICE: Could not refresh resource-parameters. Using previous one."
			else
				. /var/openqrm/openqrm-resource.conf
			fi
		fi
	else
		# here we do not found the resource_mac on one of the systems network cards
		# assuming auto-install or clone to local-disk
		/bin/cp -f /var/openqrm/openqrm-resource.conf /var/openqrm/openqrm-resource.conf.previous_res
		for RESOURCE_MAC in `ifconfig -a | grep ^eth | grep -v ":oq" | awk '{ print $5 }'`; do
			echo "NOTICE: Refreshing resource-parameters. Trying $RESOURCE_MAC."
			if $WGET -q -t 1 -T 4 -O /var/openqrm/openqrm-resource.conf "$openqrm_web_protocol://$resource_openqrmserver/openqrm/action/resource-monitor.php?resource_command=get_parameter&resource_mac=$RESOURCE_MAC"; then
				if grep -i $RESOURCE_MAC /var/openqrm/openqrm-resource.conf &>/dev/null; then
					. /var/openqrm/openqrm-resource.conf
					break
				fi
			fi
		done
	fi

	# do some extra checks for redhat/centos regarding firewall
	if [ -f /etc/redhat-release ]; then
		# iptables ?
		if which iptables 1>/dev/null; then
			if iptables -L | grep REJECT 1>/dev/null; then
				echo "NOTICE: Found iptables firewall enabled!"
				echo "NOTICE: Inserting rule to allow access to the openQRM management port $resource_execdport"
				iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport $resource_execdport -j ACCEPT
			fi
		fi
	fi

	case "$openqrm_execution_layer" in
		dropbear)
			# install and use the distro dropbear package
			DROPBEAR=`which dropbear`
			if test -z $DROPBEAR; then
				FORCE_INSTALL=true openqrm_install_os_dependency dropbear
				# on debian and ubuntu, lets make sure it is not started as a service due to our install
				if test -e /etc/default/dropbear; then
					if grep '^NO_START=0' /etc/default/dropbear 1>/dev/null|| ! grep 'NO_START' /etc/default/dropbear 1>/dev/null; then
						# looks like it has been set to start by default; let's revert that
						/etc/init.d/dropbear stop
						sed -i -e "s/^NO_START=0/NO_START=1/g" /etc/default/dropbear
						# just in case it was never there in the first place
						echo "NO_START=1" >> /etc/default/dropbear
					fi
				fi
			fi
			# start dropbear as openqrm-execd
			/bin/rm -rf $resource_basedir/openqrm/etc/dropbear
			mkdir -p $resource_basedir/openqrm/etc/dropbear/
			if ! dropbearkey -t rsa -f $resource_basedir/openqrm/etc/dropbear/dropbear_rsa_host_key; then
				echo "ERROR: Could not create host key with dropbearkey. Please check to have dropbear installed correctly!"
				return 1
			fi
			# get the public key of the openQRM server
			while (true); do
				if ! $WGET $openqrm_web_protocol://$resource_openqrmserver/openqrm/boot-service/openqrm-server-public-rsa-key; then
					if [ "$START_RETRY" == "$MAX_START_RETRY" ]; then
						echo "ERROR: Could not get the public key of the openQRM-server at $resource_openqrmserver ! Please check the certificates !"
						return 1
					fi
					START_RETRY=$(( START_RETRY + 1 ))
					sleep 1
				else
					break
				fi
			done
			if [ ! -d /root/.ssh ]; then
				mkdir -p /root/.ssh
				chmod 700 /root/.ssh
			fi
			if [ ! -f /root/.ssh/authorized_keys ]; then
				mv -f openqrm-server-public-rsa-key /root/.ssh/authorized_keys
				chmod 600 /root/.ssh/authorized_keys
			else
				OPENQRM_HOST=`cat openqrm-server-public-rsa-key | awk {' print $3 '}`
				if grep $OPENQRM_HOST /root/.ssh/authorized_keys 1>/dev/null; then
					sed -i -e "s#.*$OPENQRM_HOST.*##g" /root/.ssh/authorized_keys
				fi
				cat openqrm-server-public-rsa-key >> /root/.ssh/authorized_keys
				rm -f openqrm-server-public-rsa-key
				chmod 600 /root/.ssh/authorized_keys
			fi
			# start dropbear
			dropbear -p $resource_execdport -r $resource_basedir/openqrm/etc/dropbear/dropbear_rsa_host_key
			;;
		*)
			echo "ERROR: Un-supported command execution layer $openqrm_execution_layer ! Exiting."
			return 1
			;;
	esac

	# start openqrm-monitord
	if [ ! -d /tmp ]; then mkdir -p /tmp; fi
	nohup $resource_basedir/openqrm/sbin/openqrm-monitord 1>/tmp/openqrm-monitord.out 2>&1 &
	rm -f /tmp/openqrm-monitord.out
	# allow to overwrite the resource-configuration e.g. for cluster-resources
	if [ -f /var/openqrm/openqrm-resource.conf.static ]; then
		cat /var/openqrm/openqrm-resource.conf.static >> /var/openqrm/openqrm-resource.conf
	fi
	# set the image password - if not in the initrd
	if [ ! -f /etc/initrd-devices.conf ]; then
		if  $WGET -O /tmp/iauth.$image_id $openqrm_web_protocol://$resource_openqrmserver/openqrm/action/image-auth/iauth.$image_id.php 2>/tmp/iauth.log; then
			cryptedpassword=`cat /tmp/iauth.$image_id`
			rm -f /tmp/iauth.$image_id /tmp/iauth.log
			if [ "$cryptedpassword" != "" ]; then
				sed -i "s#^root:[^:]*#root:$cryptedpassword#" /etc/shadow
				sed -i "s#^root:[^:]*#root:$cryptedpassword#" /etc/shadow-
			fi
		fi

		# upate package manager, the boot-services may want to install additional os-deps, disabled for now
		# openqrm_update_package_manager
		# start boot-services from enabled plugins
		for boot_service in $openqrm_boot_services; do
			openqrm_boot_service $boot_service start
		done
	fi
	openqrm_post_event $resource_id "openqrm-client" 5 openqrm_client_start "Resource $resource_id fully started"
	touch ${LOCKFILE}
}


function openqrm_client_stop() {
	echo "Stopping openQRM-client"

	if [ ! -f /linuxrc ]; then
		# stop boot-services from enabled plugins
		for boot_service in $openqrm_boot_services; do
			openqrm_boot_service $boot_service stop
		done
	fi
	# stop openqrm-execd
	case "$openqrm_execution_layer" in
		dropbear)
			killall dropbear 1>/dev/null 2>&1
			for OPENQRM_PID in `ps ax 2>/dev/null | grep dropbear | grep -v grep | awk {' print $1 '}`; do
				kill $OPENQRM_PID
			done
			;;
		*)
			echo "ERROR: Un-supported command execution layer $openqrm_execution_layer ! Exiting."
			return 1
			;;
	esac
	killall openqrm-monitord 1>/dev/null 2>&1
	# in case we do not have killall (e.g. on debian-minimal install) be sure to stop the openqrm-agents anyway
	for OPENQRM_PID in `ps ax 2>/dev/null | grep openqrm-monitord | grep -v grep | awk {' print $1 '}`; do
		kill $OPENQRM_PID
	done

	# remove firewall rule for exec port
	if [ -f /etc/redhat-release ]; then
		# iptables ?
		if which iptables 1>/dev/null; then
			if iptables -L | grep REJECT 1>/dev/null; then
				iptables -D INPUT -m state --state NEW -m tcp -p tcp --dport $resource_execdport -j ACCEPT 2>/dev/null
			fi
		fi
	fi
	/bin/rm -f ${LOCKFILE}
}

function openqrm_client_status() {
	if [ -f ${LOCKFILE} ]; then
		echo "openQRM-client service is running"
	else
		echo "openQRM-client service is not running"
	fi
}



case "$1" in
	start)
		openqrm_client_start
		;;
	stop)
		openqrm_client_stop
		;;
	status)
		openqrm_client_status
		;;
	restart)
		openqrm_client_stop
		openqrm_client_start
		;;
	*)
		echo $"Usage: $0 {start|stop|status|restart}"
		exit 1
		;;
esac

